package com.qiaofang.applet.service.member.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.client.weixin.WxConfig;
import com.qiaofang.applet.common.client.weixin.WxService;
import com.qiaofang.applet.common.client.weixin.model.WxProperties;
import com.qiaofang.applet.common.context.QfContext;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.constants.BusinessConstants;
import com.qiaofang.applet.service.member.domain.Employee;
import com.qiaofang.applet.service.member.domain.Member;
import com.qiaofang.applet.service.member.domain.MemberBrowse;
import com.qiaofang.applet.service.member.repository.EmployeeRepository;
import com.qiaofang.applet.service.member.repository.MemberBrowseRepository;
import com.qiaofang.applet.service.member.repository.MemberRepository;
import com.qiaofang.applet.service.member.service.EmployeeService;
import com.qiaofang.applet.service.member.service.MemberBrowseService;
import com.qiaofang.applet.service.member.service.dto.*;
import com.qiaofang.applet.service.member.service.mapstruct.MemberBrowseMapper;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.other.util.DateTypeUtil;
import com.qiaofang.applet.service.property.domain.FirsthandEstate;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.repository.FirsthandEstateRepository;
import com.qiaofang.applet.service.property.repository.PropertyRepository;
import com.qiaofang.applet.service.property.service.dto.ShowEmpUuidDto;
import com.qiaofang.applet.service.property.service.dto.VisitorResponseDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author daiyuxiang
 */
@Slf4j
@Service
@Deprecated
public class MemberBrowseServiceImpl extends MongoBaseService<MemberBrowse, String> implements MemberBrowseService {

    private static RestTemplate restTemplate = new RestTemplate();

    private final MemberBrowseRepository repository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private MemberBrowseMapper memberBrowseMapper;

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private WxService wxService;

    @Autowired
    private FirsthandEstateRepository firsthandEstateRepository;

    @Autowired
    private PropertyRepository propertyRepository;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    private MemberBrowseService memberBrowseService;

    @Autowired
    public MemberBrowseServiceImpl(MemberBrowseRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Override
    public Page<MemberBrowse> findBusinessListByParams(MemberBrowseQueryDto queryDto, Pageable pageable) {

        Query query = new Query();

        QfContext qfContext = QfContextHolder.getContext();

        Criteria criteria = Criteria.where("corporationCode").is(qfContext.getCorporationCode());

        criteria.and("count").gt(0);

        if (StringUtils.isNotBlank(queryDto.getMemberId())) {
            criteria.and("memberId").is(queryDto.getMemberId());
        }
        if (StringUtils.isNotBlank(queryDto.getBusinessType())) {
            criteria.and("businessType").is(queryDto.getBusinessType());
        }

        query.addCriteria(criteria);

        PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.Direction.DESC, "updateTime");
        query.with(pageRequest);

        List<MemberBrowse> result = Optional.ofNullable(mongoTemplate.find(query, MemberBrowse.class))
                .orElseGet(Lists::newArrayList).stream().collect(Collectors.toList());

        return PageableExecutionUtils.getPage(result, pageable, () -> mongoTemplate.count(query, MemberBrowse.class));
    }

    /**
     * 获取excel导出数据
     *
     * @param queryDto
     * @return
     */
    @Override
    public List<MemberBrowse> getExportList(MemberBrowseListQueryDto queryDto) {
        String corporationCode = queryDto.getCorporationCode();
        Criteria criteria = Criteria.where("corporationCode").is(corporationCode);
        criteria.and("businessType").in(BusinessConstants.FIRSTHAND_ESTATE.getValue(),
                BusinessConstants.SALE_PROPERTY.getValue(), BusinessConstants.RENT_PROPERTY.getValue());
        criteria.and("count").gt(0);
//        if (StringUtils.isNotEmpty(queryDto.getCityCode())) {
//            criteria.and("cityCode").is(queryDto.getCityCode());
//        }
        if (queryDto.getBeginDate() != null && queryDto.getEndDate() != null) {
            criteria.andOperator(Criteria.where("updateTime").gte(queryDto.getBeginDate()), Criteria.where("updateTime").lt(queryDto.getEndDate()));
        }
        Query query = new Query().addCriteria(criteria);
        query.with(Sort.by(Sort.Order.desc("updateTime")));
        return mongoTemplate.find(query, MemberBrowse.class);
    }

    @Override
    public void sentWxSubscribeMessage(MemberBrowseSaveDto memberBrowseSaveDto, String employeeUniqueUuid) {

        String corporationCode = QfContextHolder.getContext().getCorporationCode();

        Corporation corporation = corporationService.getCorporationByCorporationCode(corporationCode);
        if (corporation == null) {
            throw new BusinessException("该集团不存在！");
        }
        Member member = memberRepository.findByCorporationCodeAndId(corporation.getCorporationCode(), memberBrowseSaveDto.getMemberId());

        if (member == null){
            throw new BusinessException("该用户信息不存在！");
        }

        //排除经纪人自己看自己的房源发送消息
        String employeeUniqueUuidParam = member.getEmployeeUniqueUuid();
        if (StringUtils.equals(employeeUniqueUuidParam, employeeUniqueUuid)) {
            return;
        }

        Member employeeMember = memberRepository.findFirstByCorporationCodeAndEmployeeUniqueUuid(corporation.getCorporationCode(), employeeUniqueUuid);

        if (employeeMember == null) {
            return;
        }
        WxProperties wxProperties = new WxProperties();
        wxProperties.setAppId(corporation.getAuthAppId());
        wxProperties.setAppSecret(corporation.getAuthAppSecret());

        JSONObject json = new JSONObject();
        json.put("touser",employeeMember.getOpenid());
        json.put("template_id",corporation.getTemplateId());
        Map<String, Map<String,String>> map = new HashMap();

        //小区名称+户型+面积
        String square = "";
        if (StringUtils.equals(memberBrowseSaveDto.getBusinessType(),BusinessConstants.FIRSTHAND_ESTATE.getValue())){
            FirsthandEstate firsthandEstate = firsthandEstateRepository.findFirstByEstateUniqueUuidAndCorporationCode(memberBrowseSaveDto.getBusinessUuid(), corporationCode);
            square = firsthandEstate.getBuildingAreaRange();
        } else {
            Property property = propertyRepository.findByCorporationCodeAndPropertyUniqueUuid(corporationCode, memberBrowseSaveDto.getBusinessUuid());
            square = property.getSquare().toString();
        }
        String finalSquare = "";
        if (StringUtils.isNotBlank(square)){
            finalSquare = square + "㎡";
        }
        String finalSquare1 = finalSquare;
        String data = StringUtils.defaultString(memberBrowseSaveDto.getEstateName(), "")
                + " " + StringUtils.defaultString(memberBrowseSaveDto.getHouseType(), "")
                + " " + StringUtils.defaultString(finalSquare1, "");
        if (data.length() > 20) {
            data = data.substring(0, 16) + "...";
        }
        String finalData = data;
        map.put("thing1", new HashMap<String, String>() {{
            put("value", memberBrowseSaveDto.getMemberName());
        }});
        map.put("thing2", new HashMap<String, String>() {{
            put("value", finalData);
        }});
        map.put("time3", new HashMap<String, String>() {{
            put("value", DateFormatUtils.format(new Date(), "yyyy年MM月dd日 HH:mm"));
        }});
        json.put("page","/pages/message/vistors/main");
        json.put("data",map);
        String url = String.format(WxConfig.GET_SUBSCRIBE_URI, wxService.getAccessToken(wxProperties));
        ResponseEntity<String> stringResponseEntity = null;
        try {
            stringResponseEntity = restTemplate.postForEntity(url, json, String.class);
        } catch (RestClientException e) {
            log.error("发送访客订阅消息失败：", e);
        }
        log.info("wxSubscribe:{}",stringResponseEntity.getBody());
    }

    @Override
    public void refreshBrowseStatus(String employeeUniqueUuid) {

        String corporationCode = QfContextHolder.getContext().getCorporationCode();
        Query query = new Query();
        Criteria criteria = new Criteria().and("corporationCode").is(corporationCode);
        criteria.and("businessType").ne(BusinessConstants.EMPLOYEE.getValue());
        criteria.and("read").is(false);
        Member member = memberRepository.findFirstByCorporationCodeAndEmployeeUniqueUuid(corporationCode, employeeUniqueUuid);
        //过滤自己
        if (member != null) {
            criteria.and("memberId").ne(member.getId());
        }

        criteria.and("employeeUniqueUuid").is(employeeUniqueUuid);
        //最近30天
        criteria.and("updateTime").gte(DateTypeUtil.getBeginOrAfterDay(new Date(), Calendar.DAY_OF_MONTH, -30));

        query.addCriteria(criteria);

        query.with(Sort.by(Sort.Order.desc("updateTime")));

        Update update = new Update();
        update.set("read",Boolean.TRUE);
        try {
            mongoTemplate.updateMulti(query, update, MemberBrowse.class);
        } catch (Exception e) {
           log.error("清除已读访客列表状态异常：",e);
            throw new BusinessException("清除已读访客列表状态异常：" + JSONObject.toJSONString(e));
        }
    }

    @Override
    public VisitorResponseDto getEmployeeVisitors(String employeeUniqueUuid) {

        VisitorResponseDto visitorResponseDto = new VisitorResponseDto();

        String corporationCode = QfContextHolder.getContext().getCorporationCode();
        Query query = new Query();
        Criteria criteria = new Criteria().and("corporationCode").is(corporationCode);
        criteria.and("businessType").ne(BusinessConstants.EMPLOYEE.getValue());
        Member member = memberRepository.findFirstByCorporationCodeAndEmployeeUniqueUuid(corporationCode, employeeUniqueUuid);
        //过滤自己
        if (member != null) {
            criteria.and("memberId").ne(member.getId());
        }
        criteria.and("employeeUniqueUuid").is(employeeUniqueUuid);
        //最近30天
        criteria.and("updateTime").gte(DateTypeUtil.getBeginOrAfterDay(new Date(), Calendar.DAY_OF_MONTH, -30));

        criteria.and("count").gt(0);

        query.addCriteria(criteria);

        query.with(Sort.by(Sort.Order.desc("updateTime")));

        //历史数据
        List<MemberBrowse> list = mongoTemplate.find(query, MemberBrowse.class);
        MemberBrowse memberBrowse = null;
        if (!CollectionUtils.isEmpty(list)){
            memberBrowse = list.get(0);
        }

        //未读数据
        long count = mongoTemplate.count(query.addCriteria(Criteria.where("read").is(Boolean.FALSE)), MemberBrowse.class);
        log.info("未读消息数量:{}", count);
        MemberBrowse readMemberBrowse = mongoTemplate.findOne(query, MemberBrowse.class);
        log.info("历史未读消息最新的一条记录：{}", JSONObject.toJSONString(memberBrowse));
        if (count > 0) {
            visitorResponseDto.setReadCount((int) count);
            visitorResponseDto.setLastDate(DateFormatUtils.format(readMemberBrowse.getUpdateTime(), "yyyy-MM-dd HH:mm"));
            visitorResponseDto.setText("有客户查看了您的房源，点击查看");
        } else {
            if (memberBrowse != null) {
                visitorResponseDto.setReadCount(0);
                visitorResponseDto.setLastDate(DateFormatUtils.format(memberBrowse.getUpdateTime(), "yyyy-MM-dd HH:mm"));
                visitorResponseDto.setText("暂无未读访客通知，点击查看历史");
            } else {
                visitorResponseDto.setReadCount(0);
                visitorResponseDto.setLastDate("");
                visitorResponseDto.setText("暂无访客通知");
            }
        }
        return visitorResponseDto;
    }

    @Override
    public String addOrUpdate(MemberBrowseSaveDto memberBrowseSaveDto) {
        MemberBrowseAddDto memberBrowseAddDto = new MemberBrowseAddDto();
        BeanUtils.copyProperties(memberBrowseSaveDto,memberBrowseAddDto);
        //先查有无数据
        String corporationCode = QfContextHolder.getContext().getCorporationCode();
        MemberBrowse memberBrowse = existBrowse(memberBrowseAddDto);
        String businessType = memberBrowseAddDto.getBusinessType();
        String employeeUniqueUuid = "";
        if (!businessType.equals(BusinessConstants.EMPLOYEE.getValue())){
             employeeUniqueUuid = getPropertyEmployeeToMsg(memberBrowseSaveDto.getBusinessUuid(), memberBrowseSaveDto.getBusinessType());
        }
        if (memberBrowse != null) {
            //修改更新时间  次数  归属人  已
            memberBrowse.setCount(memberBrowse.getCount() == null ? 1 : memberBrowse.getCount() + 1);
            memberBrowse.setRead(false);
            memberBrowse.setEmployeeUniqueUuid(employeeUniqueUuid);
            updateById(memberBrowse);
            return employeeUniqueUuid;
        }
        MemberBrowse params = new MemberBrowse();
        BeanUtils.copyProperties(memberBrowseSaveDto, params);
        params.setCorporationCode(corporationCode);
        params.setCreateTime(new Date());
        params.setUpdateTime(new Date());
        params.setRead(false);
        params.setCount(1);
        params.setEmployeeUniqueUuid(employeeUniqueUuid);
        memberBrowseService.insert(params);
        return employeeUniqueUuid;
    }

    private MemberBrowse existBrowse(MemberBrowseAddDto memberBrowseAddDto){
        Criteria criteria = Criteria.where("count").gt(0);
        criteria.and("memberId").is(memberBrowseAddDto.getMemberId());
        criteria.and("businessUuid").is(memberBrowseAddDto.getBusinessUuid());
        criteria.and("businessType").is(memberBrowseAddDto.getBusinessType());

        List<MemberBrowse> list = mongoTemplate.find(new Query().addCriteria(criteria), MemberBrowse.class);
        if (CollectionUtils.isEmpty(list)){
            return null;
        }
        return list.get(0);
    }


    /**
     * 获取房源固定展示为经纪人
     * @param propertyUuid
     * @return
     */
    public String getPropertyEmployeeToMsg(String propertyUuid, String businessType) {

        //二手房
        if (businessType.equals(BusinessConstants.RENT_PROPERTY.getValue())
                || businessType.equals(BusinessConstants.SALE_PROPERTY.getValue())) {
            ShowEmpUuidDto empUuidDto = employeeService.getEmployeeUuidDtoByProperty(propertyUuid);
            if (StringUtils.isBlank(empUuidDto.getFixedEmployeeUuid())) {
                //无固定展示为，取第一归属人
                Employee employee = employeeRepository.findByCompanyUuidAndEmployeeUuid(empUuidDto.getCompanyUuid(), empUuidDto.getEmployeeUuid1());
                return employee.getEmployeeUniqueUuid();
            }
            return empUuidDto.getCompanyUuid() + "_" + empUuidDto.getFixedEmployeeUuid();
        }
        //新房
        ShowEmpUuidDto empUuidDto = employeeService.getEmployeeUuidDtoByFirsthand(propertyUuid);
        if (StringUtils.isBlank(empUuidDto.getFixedEmployeeUuid())) {
            Employee employee = employeeRepository.findByCompanyUuidAndEmployeeUuid(empUuidDto.getCompanyUuid(), empUuidDto.getEmployeeUuid1());
            return employee.getEmployeeUniqueUuid();
        }
        return empUuidDto.getCompanyUuid() + "_" + empUuidDto.getFixedEmployeeUuid();
    }


}
